import { Callout } from "nextra-theme-docs";

# 快速上手

GZCTF 通过 Docker 镜像的方式提供，你可以通过 docker-compose 的方式快速部署一个功能完善的 CTF 平台。请注意，这并不是唯一的部署方式，我们更推荐使用 Kubernetes 的方式部署。相关的部署方式请参考 [部署](/zh/zh/deployment)。

<Callout type="warning">

GZCTF 的安全性和前端功能（如操作剪贴板）依赖于 HTTPS，此部分所描述的部署方式并不提供 HTTPS 支持，因此不适合用于生产环境。仅供本地测试使用。

本文档不涉及如何配置 HTTPS，关于 nginx、traefik 等软件的配置使用方法请自行查询，请注意 GZCTF 的 websocket 功能可能也需要进行独立配置，如遇到比赛通知无法推送等问题请先排查反向代理是否配置正确。

</Callout>

## 安装配置

<Callout type="info">

你需要安装 Docker 和 docker-compose 以便于快速开始使用 GZCTF，你可以在 [Docker 官网](https://docs.docker.com/engine/install/) 找到相关的安装说明。

</Callout>

1. 为了后续的配置，请准备好如下的初始化参数：

   - `GZCTF_ADMIN_PASSWORD`：初始管理员密码，在数据库未初始化时生效，需要在第一次启动时进行设置，配置在 `compose.yml` 中。
   - `POSTGRES_PASSWORD`: 数据库密码，需要配置在 `compose.yml` 中及 `appsettings.json` 中。
   - `XOR_KEY`: 用于加密比赛私钥的随机字符串，需要配置在 `appsettings.json` 中。
   - `PUBLIC_ENTRY`: 外部访问地址，可以是 IP 或域名，需要配置在 `appsettings.json` 中，用于提供给选手访问题目容器的地址。

2. 将以下内容保存为 `appsettings.json` 文件，**并替换为你的初始化参数**，具体配置说明请参考 [`appsettings.json` 配置](/zh/zh/config/appsettings)。

   ```json
   {
     "AllowedHosts": "*",
     "ConnectionStrings": {
       "Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=<Your POSTGRES_PASSWORD>"
     },
     "EmailConfig": {
       "SenderAddress": "",
       "SenderName": "",
       "UserName": "",
       "Password": "",
       "Smtp": {
         "Host": "localhost",
         "Port": 587
       }
     },
     "XorKey": "<Your XOR_KEY>",
     "ContainerProvider": {
       "Type": "Docker", // or "Kubernetes"
       "PortMappingType": "Default", // or "PlatformProxy"
       "EnableTrafficCapture": false,
       "PublicEntry": "<Your PUBLIC_ENTRY>", // or "xxx.xxx.xxx.xxx"
       // optional
       "DockerConfig": {
         "SwarmMode": false,
         "Uri": "unix:///var/run/docker.sock"
       }
     },
     "RequestLogging": false,
     "DisableRateLimit": true,
     "RegistryConfig": {
       "UserName": "",
       "Password": "",
       "ServerAddress": ""
     },
     "CaptchaConfig": {
       "Provider": "None", // or "CloudflareTurnstile" or "GoogleRecaptcha"
       "SiteKey": "<Your SITE_KEY>",
       "SecretKey": "<Your SECRET_KEY>",
       // optional
       "GoogleRecaptcha": {
         "VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify",
         "RecaptchaThreshold": "0.5"
       }
     },
     "ForwardedOptions": {
       "ForwardedHeaders": 5,
       "ForwardLimit": 1,
       "TrustedNetworks": ["192.168.12.0/8"]
     }
   }
   ```

3. 将以下内容保存为 `compose.yml` 文件，**并替换为你的初始化参数**

   ```yaml
   services:
     gzctf:
       image: registry.cn-shanghai.aliyuncs.com/gztime/gzctf:develop
       restart: always
       environment:
         - "GZCTF_ADMIN_PASSWORD=<Your GZCTF_ADMIN_PASSWORD>"
         # choose your backend language `en_US` / `zh_CN` / `ja_JP`
         - "LC_ALL=zh_CN.UTF-8"
       ports:
         - "80:8080"
       volumes:
         - "./data/files:/app/files"
         - "./appsettings.json:/app/appsettings.json:ro"
         # - "./kube-config.yaml:/app/kube-config.yaml:ro" # this is required for k8s deployment
         - "/var/run/docker.sock:/var/run/docker.sock" # this is required for docker deployment
       depends_on:
         - db

     db:
       image: postgres:alpine
       restart: always
       environment:
         - "POSTGRES_PASSWORD=<Your POSTGRES_PASSWORD>"
       volumes:
         - "./data/db:/var/lib/postgresql/data"
   ```

   <Callout type="info">

   你有可能遇到网段冲突的情况，请参考相关更改 `compose.yml`
   中的子网配置或 `/etc/docker/daemon.json` 中的网段配置。

   ```yaml
   networks:
     default:
       driver: bridge
       ipam:
         config:
           - subnet: 192.168.12.0/24
   ```

   </Callout>

4. 运行 `docker compose up -d` 来启动 GZCTF，之后你可以通过浏览器访问 GZCTF 了。

## 初始管理员

生产环境中默认不存在管理员权限用户，需要在首次启动时设置 `GZCTF_ADMIN_PASSWORD` 环境变量来设置初始管理员密码，并通过 `Admin` 账号登录。

你也可以通过手动更改数据库条目来将当前已注册的用户设置为管理员。当管理员注册完成并成功登录后，进入所选数据库表后执行：

```sql
UPDATE "AspNetUsers" SET "Role"=3 WHERE "UserName"='your_admin_user_name';
```

你可能会用到如下的命令：

```bash
docker compose exec db psql -U postgres
```

```bash
psql (15.2)
Type "help" for help.

postgres=# \c gzctf
You are now connected to database "gzctf" as user "postgres".
gzctf=# #do your sql query
```

## 使用 Redis 作为缓存

如果你想使用 Redis 作为缓存，获得更无缝的版本切换、服务端重启体验，可以在上述到配置中添加如下内容：

1. `compose.yml` 文件

   ```yaml
   services:
     gzctf:
       # ...
       depends_on:
         - db
         - cache

     cache:
       image: redis:alpine
       restart: always

     db:
       # ...
   ```

2. `appsettings.json` 文件

   ```json
   {
     "AllowedHosts": "*",
     "ConnectionStrings": {
       // ...
       "RedisCache": "cache:6379,abortConnect=false"
     }
     // ...
   }
   ```

之后重新使用 `docker compose up -d` 启动 GZCTF 即可。

## 容器镜像

GZCTF 已经预先构建并打包为统一的 Docker 镜像，你可以在 [Docker Hub](https://hub.docker.com/r/gztime/gzctf) 上找到相关的镜像。

请使用如下容器注册表获取镜像：

```txt
gztime/gzctf:latest
ghcr.io/gztimewalker/gzctf/gzctf:latest
```

<Callout type="info">

建议国内用户使用阿里云注册表（仅适用于 2024 年 6 月 20 日之后的版本）：

```txt
registry.cn-shanghai.aliyuncs.com/gztime/gzctf:latest
```

</Callout>

测试版本和开发版本请使用 `develop` 镜像标签。

## 题目配置

题目配置和题目示例请见 [GZCTF-Challenges](https://github.com/GZTimeWalker/GZCTF-Challenges) 仓库。

也可以参考和借鉴 [W4terCTF 2023](https://github.com/W4terDr0p/W4terCTF-2023) 的公开题目仓库，此内的题目均在题目正常工作的情况下尽量保证 Docker Image 的体积足够小，以便于在比赛中快速部署。

GZCTF 通过将 `GZCTF_FLAG` 环境变量注入到容器中来实现动态 flag 的分发，因此请确保题目**的容器初始化脚本**中将这个环境变量中的文本放入到合适的位置。请注意，这一环境变量的初始化是在容器启动时进行的，而非容器镜像构建时。
